package com.saitan.demo;

import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.Color;
import android.hardware.usb.UsbDevice;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Display;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.saitan.magicfilter.utils.MagicFilterType;
import com.saitan.simplertmp.RtmpHandler;
import com.saitan.uvc.UVCCameraGLSurfaceView;
import com.saitan.uvc.UVCPublisher;
import com.serenegiant.usb.IFrameCallback;
import com.serenegiant.usb.USBMonitor;
import com.serenegiant.usb.UVCCamera;

import net.ossrs.yasea.SrsEncodeHandler;
import net.ossrs.yasea.SrsLiveConfig;
import net.ossrs.yasea.SrsRecordHandler;

import java.io.IOException;
import java.net.SocketException;
import java.nio.ByteBuffer;
import java.util.Locale;
import java.util.logging.Logger;

import butterknife.BindView;
import butterknife.ButterKnife;

public class GlassActivity extends AppCompatActivity {
    private static final String TAG = "GlassActivity";

    private USBMonitor usbMonitor;
    private USBMonitor.UsbControlBlock mCtrlBlock;
    private UVCPublisher publisher;
    private static Handler handler = new Handler();
    private int flag = 0;
    private String rtmpAddress;

    private int currentPreviewWidth;
    private int currentPreviewHeight;
    private MagicFilterType currentMagicFilterType;
    private int currentTransformType;
    private int currentEncodeType;
    private int currentVideoMode;

    private float mScaleX = 1F;
    private float mScaleY = 1F;

    @BindView(R.id.lay_body)
    RelativeLayout mBodyLay;

    @BindView(R.id.lay_loading)
    LinearLayout mLoadingLay;

    @BindView(R.id.uvcCameraView)
    UVCCameraGLSurfaceView uvcCameraGLSurfaceView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_glass);

        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        //setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

        ButterKnife.bind(this);

        init();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        publisher.closeCamera();
        usbMonitor.destroy();
    }

    @Override
    protected void onResume() {
        super.onResume();
        usbMonitor.register();
        uvcCameraGLSurfaceView.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        usbMonitor.unregister();
        uvcCameraGLSurfaceView.onPause();
    }

    private void init() {
        //眼镜连接监听
        usbMonitor = new USBMonitor(this, onDeviceConnectListener);

        //预览和推流
        //rtmpAddress = "rtmp://192.168.0.110:1935/live/livestream";
        currentPreviewWidth = SrsLiveConfig.STANDARD_DEFINITION_WIDTH;
        currentPreviewHeight = SrsLiveConfig.STANDARD_DEFINITION_HEIGHT;
        currentMagicFilterType = MagicFilterType.NONE;
        currentTransformType = 3;
        currentEncodeType = 0;
        currentVideoMode = 2;

        //设置推流器
        publisher = new UVCPublisher(uvcCameraGLSurfaceView);
        publisher.setEncodeHandler(new SrsEncodeHandler(srsEncodeListener));
        publisher.setRecordHandler(new SrsRecordHandler(srsRecordListener));
        publisher.setRtmpHandler(new RtmpHandler(rtmpListener));
        publisher.setErrorCallback(errorCallback);

        //缩放比例
        Display display = getWindowManager().getDefaultDisplay();
        mScaleX = (float) display.getWidth() / currentPreviewWidth;
        mScaleY = (float) display.getHeight() / currentPreviewHeight;
    }

    //眼镜连接监听
    private USBMonitor.OnDeviceConnectListener onDeviceConnectListener = new USBMonitor.OnDeviceConnectListener() {
        @Override
        public void onAttach(UsbDevice device) {
            Log.d(TAG, "USBMonitor:onAttach");
            stopLoading();
            usbMonitor.requestPermission(device);
        }

        @Override
        public void onDetach(UsbDevice device) {
            Log.d(TAG, "USBMonitor:onDetach");
            startLoading();
        }

        @Override
        public void onConnect(UsbDevice device, USBMonitor.UsbControlBlock ctrlBlock, boolean createNew) {
            Log.d(TAG, "USBMonitor:onConnect");
            if (mCtrlBlock == null) {
                mCtrlBlock = ctrlBlock;
                runOnUiThread(() -> {
                    start(mCtrlBlock);
                });
            }
        }

        @Override
        public void onDisconnect(UsbDevice device, USBMonitor.UsbControlBlock ctrlBlock) {
            Log.d(TAG, "USBMonitor:onDisconnect");
            if (mCtrlBlock != null) {
                mCtrlBlock = null;
                runOnUiThread(() -> {
                    stop();
                });
            }
        }

        @Override
        public void onCancel(UsbDevice device) {
            Log.d(TAG, "USBMonitor:onCancel");
        }
    };

    //编码器日志监听
    private SrsEncodeHandler.SrsEncodeListener srsEncodeListener = new SrsEncodeHandler.SrsEncodeListener() {
        @Override
        public void onNetworkWeak() {
            Log.d(TAG, "onNetworkWeak");
        }

        @Override
        public void onNetworkResume() {
            Log.d(TAG, "onNetworkResume");
        }

        @Override
        public void onEncodeIllegalArgumentException(IllegalArgumentException e) {
            Log.d(TAG, "onEncodeIllegalArgumentException");
            handleException();
        }
    };

    //推流器消息监听
    private RtmpHandler.RtmpListener rtmpListener = new RtmpHandler.RtmpListener() {
        @Override
        public void onRtmpConnecting(String msg) {
            Log.d(TAG, "onRtmpConnecting:" + msg);
        }

        @Override
        public void onRtmpConnected(String msg) {
            Log.d(TAG, "onRtmpConnected:" + msg);
        }

        @Override
        public void onRtmpVideoStreaming() {
            Log.d(TAG, "onRtmpVideoStreaming");
        }

        @Override
        public void onRtmpAudioStreaming() {
            Log.d(TAG, "onRtmpAudioStreaming");
        }

        @Override
        public void onRtmpStopped() {
            Log.d(TAG, "onRtmpStopped");
        }

        @Override
        public void onRtmpDisconnected() {
            Log.d(TAG, "onRtmpDisconnected");
        }

        @Override
        public void onRtmpVideoFpsChanged(double fps) {
            //            Log.d(TAG, "onRtmpVideoFpsChanged:" + fps + "fps");
        }

        @Override
        public void onRtmpVideoBitrateChanged(double bitrate) {
            //            int rate = (int) bitrate / 1000;
            //            if (rate > 0) {
            //                Log.d(TAG, "onRtmpVideoBitrateChanged:" + rate + "kbps");
            //            } else {
            //                Log.d(TAG, "onRtmpVideoBitrateChanged:" + bitrate + "bps");
            //            }
        }

        @Override
        public void onRtmpAudioBitrateChanged(double bitrate) {
            // int rate = (int) bitrate / 1000;
            // if (rate > 0) {
            //     Logger.e("onRtmpAudioBitrateChanged:" + rate + "kbps");
            // } else {
            //     Logger.e("onRtmpAudioBitrateChanged:" + bitrate + "bps");
            // }
        }

        @Override
        public void onRtmpSocketException(SocketException e) {
            Log.d(TAG, "onRtmpSocketException");
            handleException();
        }

        @Override
        public void onRtmpIOException(IOException e) {
            Log.d(TAG, "onRtmpIOException");
            handleException();
        }

        @Override
        public void onRtmpIllegalArgumentException(IllegalArgumentException e) {
            Log.d(TAG, "onRtmpIllegalArgumentException");
            handleException();
        }

        @Override
        public void onRtmpIllegalStateException(IllegalStateException e) {
            Log.d(TAG, "onRtmpIllegalStateException");
            handleException();
        }
    };

    //录像器消息监听
    private SrsRecordHandler.SrsRecordListener srsRecordListener = new SrsRecordHandler.SrsRecordListener() {
        @Override
        public void onRecordPause() {
            Log.d(TAG, "onRecordPause");
        }

        @Override
        public void onRecordResume() {
            Log.d(TAG, "onRecordResume");
        }

        @Override
        public void onRecordStarted(String msg) {
            Log.d(TAG, "onRecordStarted:" + msg);
        }

        @Override
        public void onRecordFinished(String msg) {
            Log.d(TAG, "onRecordFinished:" + msg);
        }

        @Override
        public void onRecordIllegalArgumentException(IllegalArgumentException e) {
            Log.d(TAG, "onRecordIllegalArgumentException");
            handleException();
        }

        @Override
        public void onRecordIOException(IOException e) {
            Log.d(TAG, "onRecordIOException");
            handleException();
        }
    };

    //异常监听
    private UVCCameraGLSurfaceView.ErrorCallback errorCallback = error -> handleException();

    private void handleException() {
        stop();
    }

    //开始loading
    public void startLoading() {
        mBodyLay.post(new Runnable() {
            @Override
            public void run() {
                mBodyLay.setVisibility(View.GONE);
                mLoadingLay.setVisibility(View.VISIBLE);
            }
        });
    }

    //关闭loading
    public void stopLoading() {
        mBodyLay.post(new Runnable() {
            @Override
            public void run() {
                mBodyLay.setVisibility(View.VISIBLE);
                mLoadingLay.setVisibility(View.GONE);
            }
        });
    }

    //开始预览或推流
    private void start(USBMonitor.UsbControlBlock ctrlBlock) {
        publisher.openCamera(ctrlBlock);
        publisher.setPreviewResolution(currentPreviewWidth, currentPreviewHeight);
        publisher.setOutputResolution(currentPreviewWidth, currentPreviewHeight);
        publisher.setScreenOrientation(Configuration.ORIENTATION_LANDSCAPE);
        publisher.switchCameraFilter(currentMagicFilterType);
        if (currentVideoMode == 1) {
            publisher.setVideoSmoothMode();
        } else if (currentVideoMode == 2) {
            publisher.setVideoHDMode();
        } else if (currentVideoMode == 3) {
            publisher.setVideoFullHDMode();
        }
        if (currentEncodeType == 0) {
            publisher.switchToHardEncoder();
        } else if (currentEncodeType == 1) {
            publisher.switchToSoftEncoder();
        }
        if (currentTransformType == 1) {
            publisher.setSendAudioOnly(true);
            publisher.setSendVideoOnly(false);
        } else if (currentTransformType == 2) {
            publisher.setSendAudioOnly(false);
            publisher.setSendVideoOnly(true);
        } else if (currentTransformType == 3) {
            publisher.setSendAudioOnly(false);
            publisher.setSendVideoOnly(false);
        }

        publisher.startPreview();

        //获取图像的每一帧
        uvcCameraGLSurfaceView.setFrameCallback(frameCallback, UVCCamera.PIXEL_FORMAT_YUV420SP);
    }

    //停止预览或推流
    private void stop() {
        publisher.stopPreview();
        handler.removeCallbacksAndMessages(null);
    }

    //图像每一帧的回掉
    public IFrameCallback frameCallback = new IFrameCallback() {
        @Override
        public void onFrame(ByteBuffer byteBuffer) {
            //转换
            byte[] frameData = new byte[byteBuffer.limit() - byteBuffer.position()];
            byteBuffer.get(frameData);

            //do something
        }
    };

}
